package com.dom4j.demo;

import java.io.File;
import java.io.FileInputStream;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.DOMReader;
import org.dom4j.io.SAXReader;

import com.dom4j.demo.Dom4JVisitor;

/**
 * dom4j框架学习： 读取并解析xml
 * 
 * 
 */
public class Dom4JReadXML {

	/*
	 * 得到一个 xml 文件的 Document 对象
	 * 
	 * @param fileName 需要读取的 xml 文件的名称
	 * @return Document xml 文件对应的 org.dom4j.Document 对象
	 * 
	 * */
	public static Document read(String fileName) throws MalformedURLException, DocumentException {
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File(fileName));
		return document;
	}

	/*
	 * 打印 element 中的所有属性的值
	 * 
	 * @param e 这个 Element 中的 attribute 需要被打印 
	 * 
	 * */
	public static void printAttributeInElement(Element e) {
		for (Iterator<Attribute> iter = e.attributeIterator(); iter.hasNext();) {
			Attribute attr = iter.next();
			System.out
					.println("element: " + e.getName() + ", attributes: " + attr.getName() + " => " + attr.getValue());
		}
	}

	/*
	 * 用 iterator 遍历 element 以及其子 element 的名称, text 和 attibute
	 * 
	 * @param e 这个 Element 中的 attribute 需要被打印 
	 * 
	 * */
	public static void printAllSubElementByIterator(Element e) {

		// 打印 attribute 信息
		printAttributeInElement(e);

		// 如果没有子 element 了, 这是递归的返回条件
		if (e.elements().isEmpty()) {
			// 打印当前 element 名称和 text 信息
			System.out.println("element : " + e.getName() + ", text: " + e.getText());
			return;
		}

		// 如果还有子 element, 就递归
		for (Iterator<Element> iter = e.elementIterator(); iter.hasNext();) {
			Element subelement = iter.next();
			// 如果还有子 element, 就继续递归
			printAllSubElementByIterator(subelement);
		}

	}
	
	/*
	 * 用 visitor 遍历 element 以及其子 element 的名称, text 和 attibute
	 * 
	 * @param e 这个 Element 中的 attribute 需要被打印 
	 * 
	 * */
	public static void printAllSubElementByVisitor(Element e){
		e.accept(new Dom4JVisitor());
	}
	
	/*
	 * 输出指定名称的第一个子元素的 attribute 
	 * 
	 * @param name 子元素的名称
	 * 
	 * */
	public static void printFirstElementByName(Element root, String name){
		
		
		//获取名字为指定名称的第一个子元素
		Element firstStudentElement = root.element(name);

		// 输出其第一个属性
		System.out.println("first student Attr: " + firstStudentElement.attribute(0).getName() + "="
				+ firstStudentElement.attribute(0).getValue());
		
	}
	
	/*
	 * 通过 xpath 输出指定 element 的指定 attribute
	 * 
	 * 注意: 需要添加 dom4j 库中的 jaxen-1.1-beta-6.jar 包, 不然会报错:
	 * java.lang.NoClassDefFoundError: org/jaxen/JaxenException
	 * 	   at org.dom4j.DocumentFactory.createXPath(DocumentFactory.java:230)
	 *     at org.dom4j.tree.AbstractNode.createXPath(AbstractNode.java:207)
	 *     ...
	 * @param path    
	 *      要访问的 element 节点的名称, 如:"/class/student"
	 * @param attrName
	 * 		要访问的 element 节点的属性名称, 如"@gender"
	 * */
	
	public static void printFirstElementAttrByXPath(Document document, String path, String attrName){
		Node node = document.selectSingleNode(path);
		System.out.println("printFirstElementAttrByXPath(), element: " + node.getName() + ", attribute: " + node.valueOf(attrName));
	}
	
	
	public static void printAllElementAttrByXPath(Document document, String path){
		List list = document.selectNodes(path);
		for (Iterator iter = list.iterator(); iter.hasNext(); ) {
            Attribute attribute = (Attribute) iter.next();
            String name = attribute.getName();
            String value = attribute.getValue();
            System.out.println("attribute: " + name + "," + value);
        }
	}
	
	
	
	
	
	

}